﻿//这是ttlang的语法描述
grammar ttlang;

//语法元素只描述一个源码文件内可能出现的内容
//这里我们有三种可能出现的根节点 doc/codeblock/expr
//1.expr节点
//表达式节点我们称之为expr,表达式代表所有最终可以收敛为一个值的部分，比如 a+3*5
//而 b = a+3*5 ,则不是我们定义的表达式，他是一个语句，归属在code节点中
//2.codeblock节点
//codeblock节点就是函数体内的部分
//3.doc节点
//doc节点对应整个源代码文件
//它包含 using namespace class struct function comment 以及其它的节点



//常用片段
define:DEFINE; //# 宏
empty_line:';';
number:INT|FLOAT|HEX|BIN;//所有类型的数子
idchain:(INNERTYPE|ID) ('.' ID)?;//点链接的名字列表
arraytype:idchain('[' (DIGIT)? ']');
tupeltype:'[' type (',' type)* ']';
delegate:  '(' (value_def (',' value_def )*)? ')' '=>' type;//委托，函数签名定义的形式 
type: idchain|arraytype|tupeltype|delegate;

//@ 开头的是注解

modifiers : ('public'| 'protected'|'private'|'static'|'extern'|'primitive'|'const'|('@'expr_call))+;
//===================文档部分==========================
doc : docitem*;
docitem:using|namespace_def|class_def|struct_def|function_def|global_value_def|enum_def|comment;

value_def:(modifiers)? ID (':' type)? ('=' expr)? LEND;//变量定义

global_value_def:(modifiers)? 'var' ID (':' type)? ('=' expr)?;//全局变量定义

arg_def: ID ':' type ('=' expr)?;//参数定义

method_def:method_def_withbody|method_def_nobody; //文档函数定义
method_def_withbody:(modifiers)? ID '(' (arg_def (',' arg_def )*)? ')' (':'type)? comment* (code_block|';'); 
method_def_nobody:(modifiers)? ID '(' (arg_def (',' arg_def )*)? ')' (':'type)? ('=' ID)? comment* ;

function_def:(modifiers)? 'function' ID '(' (arg_def (',' arg_def )*)? ')' (':'type)?  code_block?; //文档函数定义

class_def:(modifiers)? 'class' (ID|INNERTYPE) '{' (value_def|method_def|define|comment|empty_line)* '}'; //class
struct_def:(modifiers)? 'struct' (ID|INNERTYPE) '{' (value_def|method_def|define|comment|empty_line)* '}'; //struct
interface_def:(modifiers)? 'struct' ID '{' (method_def)* '}';//interface

enum_item:ID ('=' number)?;
enum_def: (modifiers)? 'enum' ID (':'type)? '{' enum_item+ '}';//enun

typename_def: 'type' ID '=' type;
//@notfinish
using:'using' idchain ';';
namespace_def:'namespace' '{' (namespace_def|class_def|struct_def|function_def|global_value_def|enum_def|comment)* '}';


//====================代码块部分==========================
code_block:'{' codedoc '}';
codedoc:code_atom* ;
//代码定义
code_atom:
define|comment|empty_line //宏 注释 空行 这些杂七杂八的
|code_vaild;

code_vaild:codeelem LEND//一般的代码行
|code_block_if|code_block_for|code_block_while|code_block_dowhile|code_block_switch//各种分支语句
|code_break|code_continue
|code_block;


//代码片段：定义、赋值、自操作|
codeelem:codeelem_value_def|codeelem_set|codeelem_selfop|codeelem_expr|code_return ;
codeelem_value_def:'var' idchain (':' type)? ('=' expr)? ;//定义
codeelem_set: idchain '=' expr ;//赋值
codeelem_selfop: idchain SELF_TOKEN expr? ;//自操作
codeelem_expr: expr ;//调用

code_break:'break';
code_continue:'continue';

code_block_if:'if' '(' expr ')' code_vaild  ('else' code_vaild)?;
code_block_for:'for' '(' codeelem? ';' expr? ';' codeelem? ')' code_vaild ;
code_block_while:'while' '(' expr ')' code_vaild;
code_block_dowhile:'do'  code_vaild 'while' '(' expr ')';
code_block_switch:'switch' '(' expr ')' '{' ('case'':' codedoc)+ ('default'':' codedoc )? '}';
code_return: 'return' (expr)? ;//

//==================================表达式部分=======================
//表达式的特点是必须有值，++a 和 a++ 这种干扰操作直接在ttlang 中不作为表达式
//一元表达式无返回a++，二元表达式无返回a+=3
//三元表达式有返回 a?1|2
//数学表达式有返回,数学表达式有 四则优先级
//expr:number|STRING|idchain|BOOL
//|expr_sign
//|expr_call
//|expr_new //构造表达式
//|expr_group
//|expr_array
//|expr (MATH_TOKEN_H expr)+//高优先级数学表达式 ,直接左递归不能拆开，直接写在一起antlr可以帮忙处理
//|expr (MATH_TOKEN expr)+ //数学表达式
//|expr '?' expr ':' expr //三元表达式
//|expr '.' expr_call //加入表达式串联规则，有这条规则，idchain就大部分被盖掉了


//表达式的描述参考c语言 拆递归的做法,anltr4的递归总有些问题
//越接近expr的表达式优先级越高，且包括靠上的表达式,在展ast的时候消除掉1child 节点就好了。
//处理起来比嵌套方便
expr_prim:number|STRING|idchain|BOOL|expr_group;
expr_postfix:	expr_prim ('[' expr ']' | '('arguments? ')'| '.' idchain )?|	//后缀表达式 ++ -- 不要了，数组 成员 call
				expr_postfix ('[' expr ']' | '('arguments? ')'| '.' idchain );
expr_unary:	expr_postfix |										//元表达式，负数在这里被识别
			('&' | '*' | '+' | '-' | '~' | '!') expr_cast|		
			expr_new ;		
expr_cast:	'(' type ')' expr |									//类型转换表达式
			expr_unary;
expr_mul:	expr_cast (('*'|'/'|'%') expr_cast)?|				//乘法表达式
			expr_mul ('*'|'/'|'%') expr_cast;					
expr_add:	expr_mul (('+'|'-') expr_mul)?|						//加法表达式
			expr_add ('+'|'-') expr_mul;						
expr_shift: expr_add (('<<'|'>>') expr_add)?|					//位移表达式
			expr_shift ('<<'|'>>') expr_add;
expr_relation:	expr_shift (('<'|'>'|'<='|'>=') expr_shift)?|
				expr_relation ('<'|'>'|'<='|'>=') expr_shift;
expr_equal: expr_relation (('=='| '!=') expr_relation)?|
			expr_equal  ('=='| '!=') expr_relation ;
expr_and:	expr_equal ('&' expr_equal)?|
			expr_and '&' expr_equal;
expr_xor:	expr_and ('^' expr_and)?|
			expr_xor  '^' expr_and ;
expr_or:	expr_xor ('|' expr_xor)?|
			expr_or  '|' expr_xor;
expr_logicand:	expr_or ('&&' expr_or)?|
				expr_logicand '&&' expr_or;
expr_logicor:	expr_logicand ('||' expr_logicand)?|
				expr_logicor '||' expr_logicand;
expr_cond:expr_logicor ('?' expr ':' expr_cond)?;//三元表达式
expr:expr_cond;//根据C语言语法 赋值也属于表达式，expr自身还包括逗号表达式，这两种我们都不用
//expr_assign:	expr_cond|
//				expr_unary assignOp expr_assign;	//赋值表达式
//assignOp :   '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=';
//expr :  (assignmentOperator) (',' assignmentOperator)*;

arguments:   expr (',' expr)*;
expr_group:'(' expr ')';
expr_call:	expr_prim '('arguments? ')';//调用表达式 //被后缀表达式覆盖
//expr_array:'[' arguments ']';				//归类后缀表达式
//expr_sign: ('-'|'!'|'&') expr_cast;		//元表达式覆盖
expr_new: 'new' idchain '(' arguments? ')'; //归类元表达式

comment:COMMENTSINGLE|COMMENTMUL;
//========================词法部分===============================
//注释
COMMENTSINGLE: '//'.*? ('\r'|'\n'|EOF);
COMMENTMUL:'/*' .*? '*/';
LEND : ';';
WS	:	((' '|[\t\r\n]))+ ->skip; //WHITE SPACE 
DEFINE: '#' .*? ('\r'|'\n'|EOF); //宏


INNERTYPE:'handle'|'bool'|'float'|'double'|'uint8'|'uint16'|'uint32'|'int8'|'int16'|'int32'|'string'|'float64';

KEYWORD:'for'|'if'|'else'|'var'|'do'|'while';
BOOL:'true'|'false';
ID:[_a-zA-Z][_a-zA-Z0-9]* ;//用户自定
INT:DIGIT;
FLOAT:INT ('.' DIGIT)? 'f'? ;
HEX:'0x'([0-9]|'a'|'b'|'c'|'d'|'e'|'f'|'A'|'B'|'C'|'D'|'E'|'F')+;
BIN:'0b'([0-1])+;
DIGIT:[0-9]+;


STRING:			('"' ('\\"'|.)*? '"'  ) | ('\''('\\\''|.)*? '\''  );

SELF_TOKEN:('++'|'--'|'+='|'-='|'*='|'/='|'&='|'|=');
MATH_TOKEN: '+'|'-' |'&&' |'||' |'>'|'<'|'>='|'<='|'=='|'!=';
MATH_TOKEN_H:'*'|'/'|'%'|'^';


//定一个UNKNOWN 来识别未处理的字符,如果出现Unknown一定有识别错误
UNKNOWN__ : .;
